package main

import (
	"net/http"
	"strconv"

	"gateway-api/middlewares"
	"gateway-api/routers"
	"gateway-api/tools"

	sentinelPlugin "github.com/alibaba/sentinel-golang/pkg/adapters/gin"
	"github.com/gin-contrib/sessions"
	"github.com/gin-contrib/sessions/cookie"
	"github.com/gin-gonic/gin"
)

// go build -o gateway-api.exe main.go

func main() {
	// 初始化 Zap logger
	tools.InitLogger()

	// 设置运行模式
	gin.SetMode(tools.BugMode)

	// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	// +++++++++++++++++++++++++ http 服务 +++++++++++++++++++++++++
	// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	r := gin.Default()

	// ----------------------------------------------------------
	// ------------------- 第三方跨域中间件开始 -------------------
	// 使用自定义 Recovery 中间件（替换默认的 gin.Recovery）
	r.Use(middlewares.RecoveryMiddleware())

	// 使用解析请求参数中间件
	r.Use(middlewares.ParseArgsMiddleware)

	// 使用跨域中间件
	r.Use(middlewares.CorsMiddleware)

	// http调用熔断方式
	// r.Use(middlewares.FuseMiddleware)
	r.Use(middlewares.IsolationMiddleware)

	// 使用http调用限流方式
	r.Use(sentinelPlugin.SentinelMiddleware(
		sentinelPlugin.WithResourceExtractor(func(ctx *gin.Context) string {
			return tools.LimiterResource
		}),
		sentinelPlugin.WithBlockFallback(func(ctx *gin.Context) {
			// 返回给前端，超过了qps
			ctx.AbortWithStatusJSON(400, map[string]interface{}{
				"code":    400,
				"data":    nil,
				"message": "人气太火爆了，请稍等",
			})
		}),
	))

	// 使用 Zap 日志中间件
	r.Use(middlewares.ZapLogger())
	// ------------------- 第三方跨域中间件结束 -------------------
	// ----------------------------------------------------------

	// ----------------------- 处理错误开始 -----------------------
	// 自定义404处理
	r.NoRoute(func(c *gin.Context) {
		c.JSON(http.StatusNotFound, gin.H{
			"code":    http.StatusNotFound,
			"data":    nil,
			"message": "Not Found API",
		})
	})
	// ----------------------- 处理错误结束 -----------------------

	// 配置cookie && session
	store := cookie.NewStore([]byte("secret"))
	store.Options(sessions.Options{
		MaxAge:   7200,
		Path:     "/",
		HttpOnly: true,
	})

	//基于redis 存储session
	// store, err := redis.NewStore(10, "tcp", "localhost:6379", "", []byte("secret"))
	// if err != nil {
	// 	fmt.Println("store", err.Error())
	// 	return
	// }
	r.Use(sessions.Sessions("gin_sesstion", store))

	// 定义访问静态资源
	r.Static("/static", "./static")

	// 访问目录
	r.StaticFile("/favicon.ico", "./static/favicon.ico")
	r.StaticFile("/downloads", "./downloads")

	// 加载路由配置
	routers.ApiRouters(r)

	// -------------- 初始化 grpc client --------------
	// 连接用户微服务
	uesrServiceClientConn, err := tools.NewGrpcClientConn(tools.UesrMicroService, tools.UesrMicroServiceTag)
	if err != nil {
		tools.Zap.Error("Failed " + tools.UesrMicroService + " grpc client conn：" + err.Error())
	} else {
		tools.Zap.Info(tools.UesrMicroService + " grpc client conn success")
		tools.UserServiceClientConn = uesrServiceClientConn
	}

	// 连接公共微服务
	commonServiceClientConn, err := tools.NewGrpcClientConn(tools.CommonMicroService, tools.CommonMicroServiceTag)
	if err != nil {
		tools.Zap.Error("Failed " + tools.CommonMicroService + " grpc client conn：" + err.Error())
	} else {
		tools.Zap.Info(tools.CommonMicroService + " grpc client conn success")
		tools.CommonServiceClientConn = commonServiceClientConn
	}

	// 连接账户微服务
	accountServiceClientConn, err := tools.NewGrpcClientConn(tools.AccountMicroService, tools.AccountMicroServiceTag)
	if err != nil {
		tools.Zap.Error("Failed " + tools.AccountMicroService + " grpc client conn：" + err.Error())
	} else {
		tools.Zap.Info(tools.AccountMicroService + " grpc client conn success")
		tools.AccountServiceClientConn = accountServiceClientConn
	}

	// 运行http服务
	// go func() {
	r.Run(tools.HttpHost + ":" + strconv.Itoa(tools.HttpPort))
	// }()

	// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	// +++++++++++++++++++++++++ grpc 服务 +++++++++++++++++++++++++
	// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	// tcp协议监听指定端口号
	// lis, err := net.Listen("tcp", tools.ServiceHost+fmt.Sprintf(":%d", tools.ServicePort))
	// if err != nil {
	// tools.Zap.Fatal("Failed to listen: " + err.Error())
	// }

	// 创建JaegerTracer
	// jaegerTracer, closer, err := tools.NewJaegerTracer(tools.ServiceName, tools.JaegerAddr)
	// if err != nil {
	// tools.Zap.Fatal("Failed to create JaegerTracer: " + err.Error())
	// }
	// defer closer.Close()
	// log.Println("jaegerTracer =", jaegerTracer)

	// 实例化gRPC服务
	// srv := grpc.NewServer(
	// 加载jaegerTracer
	// grpc.UnaryInterceptor(
	// 	grpc_opentracing.UnaryServerInterceptor(grpc_opentracing.WithTracer(jaegerTracer)),
	// ),
	// )

	// 初始化注册dtm 服务
	// workflow.InitGrpc(tools.DtmGrpcServer, tools.ServiceHost+fmt.Sprintf(":%d", tools.ServicePort), srv)

	// log.Printf("grpc server listening at %v", lis.Addr())

	// 启动grpc服务
	// if err := srv.Serve(lis); err != nil {
	// 	log.Fatalf("failed to serve: %v", err)
	// }
}
